﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Elderos.Highlight.Search;
using Elderos.Ontology;

namespace Elderos.Highlight.Rules
{
    [RankingRule("CapsSequence", RuleType.Text)]
    public class RuleCapsSequence : RankingRule
    {
        public RuleCapsSequence(IOntologyData ontology)
            : base(ontology)
        {
        }

        private const int MaxCapsLength = 10;

        private readonly string[] _factorNames =
        {
            "CapsSequence_RightCount",
            "CapsSequence_LeftCount"
        };

#pragma warning disable 1998
        protected async override Task<Dictionary<TextEntity, IRuleResult>> InnerRank(HighlightResult highlightResult)
#pragma warning restore 1998
        {
            var result = new Dictionary<TextEntity, IRuleResult>();
            var tokens = highlightResult.Tokens;

            foreach (var position in highlightResult.Positions.SelectMany(x => x.SubpositionsFlattened))
            {
                if (position.IsFake) continue;

                if (position.Text != position.Text.ToUpper()) continue;
                int rightCount = 0;
                for (int i = position.TokenInterval.Last + 1; i < tokens.Length; i++)
                {
                    var token = tokens[i];
                    if (token.Length <= 2) continue;
                    if (!token.IsWord) continue;
                    if (token == token.Word.ToUpper())
                    {
                        rightCount++;
                        if (rightCount > MaxCapsLength) break;
                    }
                    else
                        break;
                }

                int leftCount = 0;
                for (int i = position.TokenInterval.First - 1; i >= 0; i--)
                {
                    string token = tokens[i];
                    if (token.Length <= 2) continue;
                    if (token == token.ToUpper())
                    {
                        leftCount++;
                        if (leftCount > 10) break;
                    }
                    else
                        break;
                }

                foreach (var textEntity in position.Entities)
                {
                    result.Add(textEntity, new ArrayResult(_factorNames, new double[] { rightCount, leftCount }));
                }
            }
            return result;
        }

        public override IRuleResult EmptyResult
        {
            get { return new ArrayResult(_factorNames, new[] { 0D, 0 }); }
        }
    }
}
